package puntaelena.graphsupport;

import puntaelena.graphsupport.solver.IFacilityLocationSolver;
import puntaelena.graphsupport.solver.NativeFacilityLocationSolver;

public class GraphSupportFront {
	public static IGraphGenerator expensiveCheapGenerator() {
		int nativeGeneratorPtr = NativeGraphSupportBridge
			.defaultExpensiveCheapGeneratorPtr();
		return new NativeGraphGenerator(nativeGeneratorPtr);
	}

	public static IFacilityLocationSolver getBinarySolver() {
		int nativeSolverPtr = NativeGraphSupportBridge.binarySolverPtr();
		return new NativeFacilityLocationSolver(nativeSolverPtr);
	}

	public static IFacilityLocationSolver getTrivialSolver() {
		int nativeSolverPtr = NativeGraphSupportBridge.trivialSolverPtr();
		return new NativeFacilityLocationSolver(nativeSolverPtr);
	}


	public static IFacilityLocationSolver getFactor3Solver() {
		int nativeSolverPtr = NativeGraphSupportBridge.factor3SolverPtr();
		return new NativeFacilityLocationSolver(nativeSolverPtr);
	}

	public static double computeFacilityLocationCost( // TODO: move 2 computator
		FacilitiesGraph fgraph,
		boolean[] isFcltOpen,
		int[] witnesses
	) {
		int citiesCount = fgraph.getCitiesCount();
		int facilitiesCount = fgraph.getFacilitiesCount();

		/*FacilitiesGraph::FacilityPriceType*/ double result = 0;

		for ( int city = 0; city < citiesCount; city++ )
		{
			int witness = witnesses[city];
			if ( witness == -1 )
			{
				return fgraph.getInfEdgeValue();
			}
			assert( witness > -1 );
			assert( witness < facilitiesCount );
			if ( !isFcltOpen[witness] )
			{
				return fgraph.getInfEdgeValue();
			}
			result += fgraph.getFSEdge( city, witness );
		}
		for ( int facility = 0; facility < facilitiesCount; facility++ )
		{
			if ( isFcltOpen[facility] )
			{
				result += fgraph.getFacilitiesPrices()[facility];
			}
		}
		return result;
	}
}
